package com.augurit.common.system.service.org.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;

import com.augurit.common.constant.OrgConstant;
import com.augurit.common.dao.AcApplicationDao;
import com.augurit.common.dao.AcServerDao;
import com.augurit.common.entity.AcApplication;
import com.augurit.common.entity.AcServer;
import com.augurit.common.syscode.service.ISysCodeService;
import com.augurit.common.syscode.web.form.SysCodeForm;
import com.augurit.common.system.convert.AcApplicationConverter;
import com.augurit.common.system.convert.AcServerConverter;
import com.augurit.common.system.service.org.IAcApplicationService;
import com.augurit.common.system.service.org.IAcFunctionService;
import com.augurit.common.system.service.org.IAcModuleService;
import com.augurit.common.system.util.OrgUtils;
import com.augurit.common.system.util.TreeUtils;
import com.augurit.common.system.web.org.form.AcApplicationForm;
import com.augurit.common.system.web.org.form.AcFunctionForm;
import com.augurit.common.system.web.org.form.AcModuleForm;
import com.augurit.common.system.web.org.form.AcServerForm;
import com.augurit.common.util.HqlUtils;
import com.augurit.common.util.PageUtils;

/**
 * 应用逻辑实现类
 */
@Service
@Transactional
public class AcApplicationServiceImpl implements IAcApplicationService {
	
	// DAO 和 Service 引用
	@Autowired
	private AcApplicationDao acApplicationDao; //应用DAO类
	
	@Autowired
	private AcServerDao acServerDao; //应用DAO类
	
	@Autowired
	private IAcModuleService acModuleService; //模块应用逻辑
	
	@Autowired
	private IAcFunctionService acFunctionService;
	
	@Autowired
	private ISysCodeService syscodeServcie;
	
	
	
	/**
	 * 根据ID获取应用Form对象
	 * @param id 应用主键ID
	 * @return 应用Form对象
	 */
	@Transactional(readOnly = true)
	public AcApplicationForm get(Long id){
		AcApplicationForm form = acApplicationDao.getForm(id);
		
		if(form.getServId() != null && form.getServId().intValue() > 0){
			AcServer serv = acServerDao.get(form.getServId());
			OrgUtils.setAcServerInfoToApp(form, serv);
		}
		
		return form;
	}

	/**
	 * 保存应用Form对象
	 * @param result 应用Form对象
	 */
	public void save(AcApplicationForm... forms){
		if(forms != null)
			for(AcApplicationForm form : forms)
				acApplicationDao.save(form);
	}
	
	/**
	 * 根据主键ID删除应用对象
	 * @param id 应用主键ID
	 */
	public void delete(Long... ids) {
		if(ids != null)
			acApplicationDao.delete(ids);
	}

	/**
	 * 级联删除应用
	 * @param appId 应用的主键ID
	 */
	public void deleteAppCascade(Long... appIds) {
		if(appIds != null){
			for(Long appId : appIds){
				
				// 删除应用的所有模块和子模块
				Long[] moduleIds = acModuleService.getModuleIds(appId);
				acModuleService.deleteModuleCascade(moduleIds);
				
				// 删除应用对象本身
				acApplicationDao.delete(appId);
			}
		}
	}
	
	/**
	 * 添加应用
	 * @param form
	 */
	public void saveAppCascade(AcApplicationForm form){
		acApplicationDao.saveCascade(form);
	}
	
	/**
	 * 获取所有的应用ID集合
	 * @return 应用ID集合
	 */
	public Long[] getAllAppIds(){
		return acApplicationDao.getAllAppIds();
	}
	
	
	/**
	 * 查询所有的应用系统
	 * @return 应用form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcApplicationForm> getAllApps(){
		List<AcApplication> list = acApplicationDao.getAll();
		return AcApplicationConverter.convertToFormList(list);
	}
	
	/**
	 * 分页获取所有应用
	 * @param page 分页对象
	 * @return 包含应用form分页对象
	 */
	@Transactional(readOnly = true)
	public Page<AcApplicationForm> getAllApps(Page<AcApplicationForm> page){
		return getAllApps(page, null);
	}
	
	/**
	 * 多条件查询，分页获取所有应用
	 * @param page 分页对象
	 * @param form 查询条件
	 * @return 包含应用form分页对象
	 */
	@Transactional(readOnly = true)
	public Page<AcApplicationForm> getAllApps(Page<AcApplicationForm> page, AcApplicationForm form){
		// 建立新的分页对象
		Page<AcApplication> pg = PageUtils.newPageInstance(page);
		
		// 按过滤条件分页查找对象
		StringBuffer hql = new StringBuffer("from AcApplication app where 1=1 ");
		List values = new ArrayList();
		
		if(form != null){
			if(form.getAppName() != null && form.getAppName().trim().length() > 0){
				hql.append(" and app.appName like ?");
				values.add("%" + form.getAppName() + "%");
			}
			if(form.getAppCode() != null && form.getAppCode().trim().length() > 0){
				hql.append(" and app.appCode like ?");
				values.add("%" + form.getAppCode() + "%");
			}
		}
		
		//排序
		hql.append(HqlUtils.buildOrderBy(page, "app"));
		
		acApplicationDao.findPage(pg, hql.toString(), values);
		
		// 转换为Form对象列表并赋值到原分页对象中
		List<SysCodeForm> appTypeList = syscodeServcie.getItems(OrgConstant.SYS_CODE_APP_TYPE);
		List<AcServerForm> acServerList = AcServerConverter.convertToFormList(acServerDao.getAll());
		List<AcApplicationForm> list = AcApplicationConverter.convertToFormList(pg.getResult(), acServerList, appTypeList);

		PageUtils.copy(pg, list, page);
		return page;
	}
	
	/**
	 * 获取指定应用的直属模块列表
	 * @param appId 应用ID
	 * @return 直属模块form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getModules(Long appId){
		return acModuleService.getModules(appId);
	}
	
	/**
	 * 分页获取指定应用的直属模块列表
	 * @param appId 应用ID
	 * @return 直属模块form对象列表
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getModules(Long appId, Page<AcModuleForm> page, Map<String, List<SysCodeForm>> sysCodeBuffer){
		return acModuleService.getModules(appId, page, sysCodeBuffer);
	}
	
	/**
	 * 获取指定应用的所有模块列表
	 * @param appId 应用ID
	 * @return 所有模块form对象列表
	 */
	@Transactional(readOnly = true)
	public List<AcModuleForm> getAllModules(Long appId){
		return acModuleService.getAllModules(appId);
	}

	/**
	 * 分页获取指定应用的所有模块列表
	 * @param appId 应用ID
	 * @return 所有模块form对象列表
	 */
	@Transactional(readOnly = true)
	public Page<AcModuleForm> getAllModules(Long appId, Page<AcModuleForm> page) {
		return acModuleService.getAllModules(appId, page);
	}
	
	/**
	 * 把相应的功能关联到模块
	 * @param modulesList 模块列表
	 * @param funcsList   功能列表
	 */
	private void associateFunsToModule(List<AcModuleForm> modulesList, List<AcFunctionForm> funcsList){
		
		if(modulesList != null && funcsList != null){
			for(AcFunctionForm funcForm : funcsList){
				
				for(AcModuleForm moduleForm : modulesList){
					
					if(funcForm.getModuleId().intValue() == moduleForm.getModuleId().intValue()){
						
						if(moduleForm.getFunctions() == null)
							moduleForm.setFunctions(new ArrayList<AcFunctionForm>());
						
						moduleForm.getFunctions().add(funcForm);
					}
				}
			}
		}
		
	}
	/**
	 * 获取指定应用的树结构，包括模块、子模块、功能
	 * @param appId 应用id
	 * @param isSetMenuName 是否设置与功能关联的菜单名称
	 * @return 应用form对象
	 */
	@Transactional(readOnly = true)
	public AcApplicationForm getTreeByApp(AcApplicationForm app, boolean isSetMenuName){
		AcApplicationForm acApplicationForm = app;
		
		//获取应用的所有模块(包括直属模块和子模块)
		List<AcModuleForm> children = this.getAllModules(acApplicationForm.getAppId());
		
		//获取应用下的所有的功能(包括子模块下的功能)
		List<AcFunctionForm> funcs = acModuleService.getFuncs(OrgUtils.getModuleIds(children));
		
		if(funcs != null && funcs.size() > 0){
			//加载功能关联菜单信息
			if(isSetMenuName)
				acFunctionService.loadMenuNamesOfFunc(funcs);
			
			associateFunsToModule(children, funcs);
		}
	

		//构造应用下的树结构
		List<AcModuleForm> list = TreeUtils.constructModuleTree(children);
		acApplicationForm.setChildren(list);
		
		//直属模块构造树结构
		return acApplicationForm;
	}
	
	/**
	 * 获取应用列表的树结构，包括模块、子模块、功能
	 * @param appIds 应用id数组
	 * @return 应用form对象列表
	 */
	public List<AcApplicationForm> getTreeByApps(List<AcApplicationForm> apps, boolean isSetMenuName){
		if(apps != null && apps.size() > 0){
			List<AcApplicationForm> result = new ArrayList();
			
			for(AcApplicationForm app : apps){
				result.add(getTreeByApp(app, isSetMenuName));
			}
			
			return result;
		}
		return null;
	}
	
	/**
	 * 新建模块
	 * @param form 模块form对象
	 */
	public void addModuleCascade(AcModuleForm form){
		if(form != null)
			acModuleService.addModuleCascade(form);
	}
	
	/**
	 * 删除模块
	 * @param moduleId 模块id
	 */
	public void deleteModuleCascade(Long moduleId){
		if(moduleId != null)
			acModuleService.deleteModuleCascade(moduleId);
	}
}
